using System;
using System.Data;
using System.EnterpriseServices;
using PCSComMaterials.Inventory.DS;
using PCSComSale.Order.DS;
using PCSComUtils.Common;
using PCSComUtils.Common.BO;
using PCSComUtils.MasterSetup.DS;
using PCSComUtils.PCSExc;
using System.Linq;
using System.Transactions;
using System.Collections.Generic;
using PCSComUtils.DataContext;
using PCSComUtils.DataAccess;
using System.Data.SqlClient;
namespace PCSComSale.Order.BO
{
	public class SOConfirmShipManagementBO
	{
        private const string THIS = "PCSComSale.Order.BO.SOConfirmShipManagementBO";
		
		/// <summary>
		/// List confirmable from commit inventory
		/// </summary>
		/// <param name="pintCommitMasterID"></param>
		/// <returns></returns>
		public DataSet ListConfirmable(int pintCommitMasterID)
		{
			SO_CommitInventoryDetailDS dsDetail = new SO_CommitInventoryDetailDS();
			return dsDetail.ListToConfirm(pintCommitMasterID);
		}
		
		public object GetSaleOrderMasterVO(int pintSOMasterID)
		{
            SO_SaleOrderMasterDS dsSOMaster = new SO_SaleOrderMasterDS();
            return dsSOMaster.GetObjectVO(pintSOMasterID);
		}

		public DataSet GetCommitedDelSchLines(int pintSOMasterID, string strGateIDs)
		{
			SO_ConfirmShipMasterDS dsMaster = new SO_ConfirmShipMasterDS();
			return dsMaster.GetCommitedDelSchLines(pintSOMasterID, strGateIDs);
		}

		public DataSet GetCommitedDelSchLines(int pintSOMasterID, string strGateIDs, DateTime pdtmFromDate, DateTime pdtmToDate)
		{
			SO_ConfirmShipMasterDS dsMaster = new SO_ConfirmShipMasterDS();
			return dsMaster.GetCommitedDelSchLines(pintSOMasterID, strGateIDs, pdtmFromDate, pdtmToDate);
		}

		public DataSet GetExistedForView(int pintMasterID, bool pblnIsInvoice)
		{
			DataSet dstData = null;
			if (!pblnIsInvoice)
			{
				SO_ConfirmShipDetailDS dsCSDetail = new SO_ConfirmShipDetailDS();
				dstData = dsCSDetail.ListForReview(pintMasterID);
			}
			else
			{
				SO_InvoiceDetailDS dsCSDetail = new SO_InvoiceDetailDS();
				dstData = dsCSDetail.ListForReview(pintMasterID);
			}
			return dstData;
		}
		
		public void DeleteConfirmShipment(int pintConfirmMasterID, int pintSaleOrderMasterID, DataSet dstCSDetail, DataSet pdstCommit,
			DataSet pdstMasLocCache, DataSet pdstLocCache, DataSet pdstBinCache,
			DataSet pdstSODetail, int pintOldTranType, int pintNewTranType)
		{
			IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
			IV_LocationCacheDS dsLocCache = new IV_LocationCacheDS();
			IV_MasLocCacheDS dsMasLocCache = new IV_MasLocCacheDS();
			MST_TransactionHistoryDS dsTransaction = new MST_TransactionHistoryDS();
			
			SO_CommitInventoryDetailDS dsCommitInventory = new SO_CommitInventoryDetailDS();
			SO_SaleOrderDetailDS dsSODetail = new SO_SaleOrderDetailDS();
			
			dsCommitInventory.UpdateDataSetForShippingManagement(pdstCommit);
				
			#region update cache

			// bin cache
			dsBinCache.UpdateDataSet(pdstBinCache);

			// location cache
			dsLocCache.UpdateDataSet(pdstLocCache);

			// master location cache
			dsMasLocCache.UpdateDataSet(pdstMasLocCache);

			#endregion

			// update transaction history
			dsTransaction.UpdateTranType(pintConfirmMasterID, pintOldTranType, pintNewTranType, 22);

			dsSODetail.UpdateDataSet(pdstSODetail);

			//update saleorder if ship completed
			SO_SaleOrderMasterDS dsSOMaster = new SO_SaleOrderMasterDS();
			dsSOMaster.UpdateShipCompleteByID(pintSaleOrderMasterID, false);

			// delete detail
			SO_ConfirmShipDetailDS dsDetail = new SO_ConfirmShipDetailDS();
			dsDetail.Delete(pintConfirmMasterID);
			// delete master
			SO_ConfirmShipMasterDS dsMaster = new SO_ConfirmShipMasterDS();
			dsMaster.Delete(pintConfirmMasterID);
		}

		public DataSet ListByMaster(int pintMasterID)
		{
			SO_ConfirmShipDetailDS dsDetail = new SO_ConfirmShipDetailDS();
			return dsDetail.ListByMaster(pintMasterID);
		}
		public DataSet ListCommit()
		{
			SO_CommitInventoryDetailDS dsCommitInventory = new SO_CommitInventoryDetailDS();
			return dsCommitInventory.ListCommit();
		}
		public DataRow GetMasterVO(int pintMasterID)
		{
			SO_ConfirmShipMasterDS dsMaster = new SO_ConfirmShipMasterDS();
			return dsMaster.GetMasterObject(pintMasterID);
		}

        public int InsertConfirmShipment(SO_ConfirmShipMasterVO pvoMaster, DataSet dstCSDetail, DataSet pdstCommit,
			DataSet pdstMasLocCache, DataSet pdstLocCache, DataSet pdstBinCache,
            List<int> completedSaleOrderDetails , DataSet pdstTransaction, DataSet pdstData)
        {
            string METHOD_NAME =THIS+ ".InsertConfirmShipment()";
            int intMasterID;
            using (var trans = new TransactionScope())
            {
                using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
                {
                    try
                    {
                        SO_ConfirmShipMaster objMaster = new SO_ConfirmShipMaster();
                        
                        #region Insert SO_ConfirmShipMaster
                        objMaster.ConfirmShipNo = pvoMaster.ConfirmShipNo;
                        if (pvoMaster.ShippedDate != DateTime.MinValue)
                        {
                            objMaster.ShippedDate = pvoMaster.ShippedDate;
                        }
                        if (pvoMaster.SaleOrderMasterID > 0)
                        {
                            objMaster.SaleOrderMasterID = pvoMaster.SaleOrderMasterID;
                        }
                        if (pvoMaster.MasterLocationID > 0)
                        {
                            objMaster.MasterLocationID = pvoMaster.MasterLocationID;
                        }
                        if (pvoMaster.CurrencyID > 0)
                        {
                            objMaster.CurrencyID = pvoMaster.CurrencyID;
                        }
                        if (pvoMaster.ExchangeRate !=0)
                        {
                            objMaster.ExchangeRate = pvoMaster.ExchangeRate;
                        }
                        objMaster.ShipCode = pvoMaster.ShipCode;
                        objMaster.FromPort = pvoMaster.FromPort;
                        objMaster.CNo = pvoMaster.CNo;

                        objMaster.Measurement = pvoMaster.Measurement;
                        objMaster.GrossWeight = pvoMaster.GrossWeight;
                        objMaster.NetWeight = pvoMaster.NetWeight;

                        objMaster.IssuingBank = pvoMaster.IssuingBank;
                        objMaster.LCNo = pvoMaster.LCNo;
                        objMaster.VesselName = pvoMaster.VesselName;

                        objMaster.Comment = pvoMaster.Comment;
                        objMaster.ReferenceNo = pvoMaster.ReferenceNo;
                        objMaster.InvoiceNo = pvoMaster.InvoiceNo;
                        if (pvoMaster.LCDate != DateTime.MinValue)
                        {
                            objMaster.LCDate = pvoMaster.LCDate;
                        }
                        if (pvoMaster.OnBoardDate != DateTime.MinValue)
                        {
                            objMaster.OnBoardDate = pvoMaster.OnBoardDate;
                        }
                        if (pvoMaster.InvoiceDate != DateTime.MinValue)
                        {
                            objMaster.InvoiceDate = pvoMaster.InvoiceDate;
                        }
                        objMaster.CCNID = pvoMaster.CCNID;
                        db.SO_ConfirmShipMasters.InsertOnSubmit(objMaster);
                        db.SubmitChanges();
                        intMasterID = objMaster.ConfirmShipMasterID;
                        #endregion

                        foreach (DataRow dr in dstCSDetail.Tables[0].Rows)
                        {
                            if (dr.RowState == DataRowState.Deleted)
                                continue;
                            dr[SO_ConfirmShipDetailTable.CONFIRMSHIPMASTERID_FLD] = intMasterID;
                        }
                        foreach (DataRow dr in pdstTransaction.Tables[0].Rows)
                        {
                            dr[MST_TransactionHistoryTable.REFMASTERID_FLD] = intMasterID;
                        }
                        
                        #region Insert SO_CommitInventoryDetail
                        if (pdstData != null && pdstData.Tables.Count > 0)
                        {
                            foreach (DataRow dr1 in pdstData.Tables[0].Rows)
                            {
                                int intDeliveryID = Convert.ToInt32(dr1[SO_DeliveryScheduleTable.DELIVERYSCHEDULEID_FLD]);
                                DataRow[] drowCommits = pdstCommit.Tables[0].Select(SO_DeliveryScheduleTable.DELIVERYSCHEDULEID_FLD + "=" + intDeliveryID);
                                foreach (DataRow dr2 in drowCommits)
                                {
                                    int iSOCommitInventoryMasterID = Convert.ToInt32(dr2[SO_CommitInventoryDetailTable.COMMITINVENTORYMASTERID_FLD]);
                                    var listData = from objdata in db.SO_CommitInventoryDetails
                                                   where objdata.CommitInventoryMasterID == iSOCommitInventoryMasterID
                                                                   select objdata;

                                    foreach (SO_CommitInventoryDetail obj in listData)
                                    {
                                        if (obj != null)
                                        {
                                            obj.Shipped = true;
                                            obj.ShipDate = pvoMaster.ShippedDate;
                                            db.SubmitChanges();
                                        }
                                    }
                                    
                                }
                            }
                           
                        }
                        #endregion

                        #region update cache
                        if (pdstData != null && pdstData.Tables.Count > 0)
                        {
                            foreach (DataRow dr in pdstData.Tables[0].Rows)
                            {
                                try
                                {
                                    //Update OHQuantity BinCache
                                    int iLocationID = Convert.ToInt32(dr["LocationID"]);
                                    int iMasterLocationID = Convert.ToInt32(dr["MasterLocationID"]); ;
                                    int iProductID = Convert.ToInt32(dr["ProductID"]);
                                    int iBinID = Convert.ToInt32(dr["BinID"]);
                                    decimal dOHQuantity = 0;
                                    decimal dCommitQuantity = 0;
                                    if (dr[SO_ConfirmShipDetailTable.INVOICEQTY_FLD] != DBNull.Value)
                                    {
                                        dOHQuantity = Convert.ToDecimal(dr[SO_ConfirmShipDetailTable.INVOICEQTY_FLD]);
                                    }
                                    if (dr["CommitQuantity"] != DBNull.Value)
                                    {
                                        dCommitQuantity = Convert.ToDecimal(dr["CommitQuantity"]);
                                    }
                                    IV_BinCache objBin = new IV_BinCache();
                                    objBin = db.IV_BinCaches.SingleOrDefault(e => e.LocationID == iLocationID && e.BinID == iBinID && e.ProductID == iProductID);
                                    if (objBin != null)
                                    {
                                        if (objBin.OHQuantity != null)
                                        {
                                            if (dr[SO_ConfirmShipDetailTable.INVOICEQTY_FLD] != DBNull.Value)
                                            {
                                                if (objBin.OHQuantity - dOHQuantity >= 0)
                                                {
                                                    objBin.OHQuantity = objBin.OHQuantity - dOHQuantity;
                                                }
                                                else
                                                {
                                                    throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                        }
                                        if (objBin.CommitQuantity != null)
                                        {
                                            if (dr["CommitQuantity"] != DBNull.Value)
                                            {
                                                if (objBin.CommitQuantity - dCommitQuantity >= 0)
                                                {
                                                    objBin.CommitQuantity = objBin.CommitQuantity - dCommitQuantity;
                                                }
                                                else
                                                {
                                                    throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                        }
                                    }
                                    else
                                    {
                                        throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                    }

                                    IV_LocationCache objLocation = new IV_LocationCache();
                                    objLocation = db.IV_LocationCaches.SingleOrDefault(e => e.LocationID == iLocationID && e.ProductID == iProductID);
                                    if (objLocation != null)
                                    {
                                        if (objLocation.OHQuantity != null)
                                        {
                                            if (objLocation.OHQuantity - dOHQuantity >= 0)
                                            {
                                                objLocation.OHQuantity = objLocation.OHQuantity - dOHQuantity;
                                            }
                                            else
                                            {
                                                throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                            }
                                        }
                                        else
                                        {
                                            throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                        }
                                        if (objLocation.CommitQuantity != null)
                                        {
                                            if (objLocation.CommitQuantity - dCommitQuantity >= 0)
                                            {
                                                objLocation.CommitQuantity = objLocation.CommitQuantity - dCommitQuantity;
                                            }
                                            else
                                            {
                                                throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                            }
                                        }
                                        else
                                        {
                                            throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                        }
                                    }
                                    else
                                    {
                                        throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                    }
                                    IV_MasLocCache objMasLocation = new IV_MasLocCache();
                                    objMasLocation = db.IV_MasLocCaches.SingleOrDefault(e => e.ProductID == iProductID && e.MasterLocationID == iMasterLocationID);
                                    if (objMasLocation != null)
                                    {
                                        if (objMasLocation.OHQuantity != null)
                                        {
                                            if (objMasLocation.OHQuantity - dOHQuantity >= 0)
                                            {
                                                objMasLocation.OHQuantity = objMasLocation.OHQuantity - dOHQuantity;
                                            }
                                            else
                                            {
                                                throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                            }
                                        }
                                        else
                                        {
                                            throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                        }
                                        if (objMasLocation.CommitQuantity != null)
                                        {
                                            if (objMasLocation.CommitQuantity - dCommitQuantity >= 0)
                                            {
                                                objMasLocation.CommitQuantity = objMasLocation.CommitQuantity - dCommitQuantity;
                                            }
                                            else
                                            {
                                                throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                            }
                                        }
                                        else
                                        {
                                            throw new PCSException(ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY, iProductID.ToString(), null);
                                        }

                                    }
                                }
                                catch (PCSBOException ex)
                                {
                                    if (ex.mCode == ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY)
                                        throw new PCSDBException(ErrorCode.MESSAGE_NOT_ENOUGH_COMPONENT_TO_COMPLETE, METHOD_NAME, ex);
                                    throw new PCSDBException(ErrorCode.ERROR_DB, METHOD_NAME, ex);
                                }
                             }
                        }

                        #endregion

                        #region update transaction history
                        if (pdstTransaction.Tables.Count > 0)
                        {
                            IList<MST_TransactionHistory> listTranstion = new List<MST_TransactionHistory>();
                            foreach (DataRow dr in pdstTransaction.Tables[0].Rows)
                            {
                                MST_TransactionHistory obj = new MST_TransactionHistory();
                                if (dr[MST_TransactionHistoryTable.MASTERLOCATIONID_FLD] != DBNull.Value)
                                {
                                    obj.MasterLocationID = Convert.ToInt32(dr[MST_TransactionHistoryTable.MASTERLOCATIONID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.BINID_FLD] != DBNull.Value)
                                {
                                    obj.BinID = Convert.ToInt32(dr[MST_TransactionHistoryTable.BINID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.BUYSELLCOST_FLD] != DBNull.Value)
                                {
                                    obj.BuySellCost = Convert.ToDecimal(dr[MST_TransactionHistoryTable.BUYSELLCOST_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.INSPSTATUS_FLD]!=DBNull.Value)
                                {
                                    obj.InspStatus = Convert.ToByte(dr[MST_TransactionHistoryTable.INSPSTATUS_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.TRANSDATE_FLD] != DBNull.Value)
                                {
                                    obj.TransDate = Convert.ToDateTime(dr[MST_TransactionHistoryTable.TRANSDATE_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.POSTDATE_FLD] != DBNull.Value)
                                {
                                    obj.PostDate = Convert.ToDateTime(dr[MST_TransactionHistoryTable.POSTDATE_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.REFMASTERID_FLD] != DBNull.Value)
                                {
                                    obj.RefMasterID = Convert.ToInt32(dr[MST_TransactionHistoryTable.REFMASTERID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.REFDETAILID_FLD] != DBNull.Value)
                                {
                                    obj.RefDetailID = Convert.ToInt32(dr[MST_TransactionHistoryTable.REFDETAILID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.COST_FLD] != DBNull.Value)
                                {
                                    obj.StdCost = Convert.ToDecimal(dr[MST_TransactionHistoryTable.COST_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.CCNID_FLD] != DBNull.Value)
                                {
                                    obj.CCNID = Convert.ToInt32(dr[MST_TransactionHistoryTable.CCNID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.TRANTYPEID_FLD] != DBNull.Value)
                                {
                                    obj.TranTypeID = Convert.ToInt32(dr[MST_TransactionHistoryTable.TRANTYPEID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.PARTYID_FLD] != DBNull.Value)
                                {
                                    obj.PartyID = Convert.ToInt32(dr[MST_TransactionHistoryTable.PARTYID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.PARTYLOCATIONID_FLD] != DBNull.Value)
                                {
                                    obj.PartyLocationID = Convert.ToInt32(dr[MST_TransactionHistoryTable.PARTYLOCATIONID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.LOCATIONID_FLD] != DBNull.Value)
                                {
                                    obj.LocationID = Convert.ToInt32(dr[MST_TransactionHistoryTable.LOCATIONID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.PRODUCTID_FLD] != DBNull.Value)
                                {
                                    obj.ProductID = Convert.ToInt32(dr[MST_TransactionHistoryTable.PRODUCTID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.STOCKUMID_FLD] != DBNull.Value)
                                {
                                    obj.StockUMID = Convert.ToInt32(dr[MST_TransactionHistoryTable.STOCKUMID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.CURRENCYID_FLD] != DBNull.Value)
                                {
                                    obj.CurrencyID = Convert.ToInt32(dr[MST_TransactionHistoryTable.CURRENCYID_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.QUANTITY_FLD] != DBNull.Value)
                                {
                                    obj.Quantity = Convert.ToDecimal(dr[MST_TransactionHistoryTable.QUANTITY_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.MASLOCOHQUANTITY_FLD] != DBNull.Value)
                                {
                                    obj.MasLocOHQuantity = Convert.ToDecimal(dr[MST_TransactionHistoryTable.MASLOCOHQUANTITY_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.LOCATIONOHQUANTITY_FLD] != DBNull.Value)
                                {
                                    obj.LocationOHQuantity = Convert.ToDecimal(dr[MST_TransactionHistoryTable.LOCATIONOHQUANTITY_FLD]);
                                }
                                if (dr[MST_TransactionHistoryTable.BINOHQUANTITY_FLD] != DBNull.Value)
                                {
                                    obj.BinOHQuantity = Convert.ToDecimal(dr[MST_TransactionHistoryTable.BINOHQUANTITY_FLD]);
                                }
                                obj.Comment = dr[MST_TransactionHistoryTable.COMMENT_FLD].ToString();
                                if (dr[MST_TransactionHistoryTable.EXCHANGERATE_FLD] != DBNull.Value)
                                {
                                    obj.ExchangeRate = Convert.ToDecimal(dr[MST_TransactionHistoryTable.EXCHANGERATE_FLD]);
                                }
                                obj.Lot =dr[MST_TransactionHistoryTable.LOT_FLD].ToString();

                                obj.Serial = dr[MST_TransactionHistoryTable.SERIAL_FLD].ToString();
                                if (dr[MST_TransactionHistoryTable.OLDAVGCOST_FLD] != DBNull.Value)
                                {
                                    obj.OldAvgCost = Convert.ToDecimal(dr[MST_TransactionHistoryTable.OLDAVGCOST_FLD]);
                                }
                                obj.UserName = SystemProperty.UserName;
                                if (dr[MST_TransactionHistoryTable.NEWAVGCOST_FLD] != DBNull.Value)
                                {
                                    obj.NewAvgCost = Convert.ToDecimal(dr[MST_TransactionHistoryTable.NEWAVGCOST_FLD]);
                                }
                                listTranstion.Add(obj);
                              
                            }
                            db.MST_TransactionHistories.InsertAllOnSubmit(listTranstion);
                            db.SubmitChanges();
                        }
                        #endregion

                        #region Update confirm ship detail

                        if (dstCSDetail != null && dstCSDetail.Tables.Count > 0)
                        {
                            IList<SO_ConfirmShipDetail> listConfirmShip = new List<SO_ConfirmShipDetail>();
                            foreach (DataRow dr in dstCSDetail.Tables[0].Rows)
                            {
                                SO_ConfirmShipDetail obj = new SO_ConfirmShipDetail();
                                if (dr[SO_ConfirmShipDetailTable.CONFIRMSHIPMASTERID_FLD] != DBNull.Value)
                                {
                                    obj.ConfirmShipMasterID =
                                        Convert.ToInt32(dr[SO_ConfirmShipDetailTable.CONFIRMSHIPMASTERID_FLD]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.DELIVERYSCHEDULEID_FLD] != DBNull.Value)
                                {
                                    obj.DeliveryScheduleID =
                                        Convert.ToInt32(dr[SO_ConfirmShipDetailTable.DELIVERYSCHEDULEID_FLD]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.PRICE_FLD] != DBNull.Value)
                                {
                                    obj.Price = Convert.ToDecimal(dr[SO_ConfirmShipDetailTable.PRICE_FLD]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.INVOICEQTY_FLD] != DBNull.Value)
                                {
                                    obj.InvoiceQty = Convert.ToDecimal(dr[SO_ConfirmShipDetailTable.INVOICEQTY_FLD]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.VATAMOUNT_FLD] != DBNull.Value)
                                {
                                    obj.VATAmount = Convert.ToDecimal(dr[SO_ConfirmShipDetailTable.VATAMOUNT_FLD]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.VATPERCENT_FLD] != DBNull.Value)
                                {
                                    obj.VATPercent = Convert.ToDecimal(dr[SO_ConfirmShipDetailTable.VATPERCENT_FLD]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.PRODUCTID_FLD] != DBNull.Value)
                                {
                                    obj.ProductID = Convert.ToInt32(dr[SO_ConfirmShipDetailTable.PRODUCTID_FLD]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.SALEORDERDETAILID_FLD] != DBNull.Value)
                                {
                                    obj.SaleOrderDetailID =
                                        Convert.ToInt32(dr[SO_ConfirmShipDetailTable.SALEORDERDETAILID_FLD]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.OHQuantity] != DBNull.Value)
                                {
                                    obj.OHQuantity = Convert.ToDecimal(dr[SO_ConfirmShipDetailTable.OHQuantity]);
                                }
                                if (dr[SO_ConfirmShipDetailTable.CommittedQuantity] != DBNull.Value)
                                {
                                    obj.CommittedQuantity =
                                        Convert.ToDecimal(dr[SO_ConfirmShipDetailTable.CommittedQuantity]);
                                }
                                listConfirmShip.Add(obj);
                            }
                            db.SO_ConfirmShipDetails.InsertAllOnSubmit(listConfirmShip);
                            db.SubmitChanges();
                        }

                        #endregion

                        var saleOrderMasters = new List<SO_SaleOrderMaster>();
                        #region mark sale order detail as ship completed

                        if (completedSaleOrderDetails != null)
                        {
                            foreach (int saleOrderDetailId in completedSaleOrderDetails)
                            {
                                var saleDetail = db.SO_SaleOrderDetails.SingleOrDefault(e => e.SaleOrderDetailID == saleOrderDetailId);
                                if (saleDetail != null)
                                {
                                    saleDetail.ShipCompleted = true;
                                    if (!saleOrderMasters.Contains(saleDetail.SO_SaleOrderMaster))
                                    {
                                        saleOrderMasters.Add(saleDetail.SO_SaleOrderMaster);
                                    }
                                    db.SubmitChanges();
                                }
                            }
                        }
                        #endregion

                        #region mark sale order master as ship completed

                        foreach (var saleOrderMaster in saleOrderMasters)
                        {
                            var isCompleted = saleOrderMaster.SO_SaleOrderDetails.All(soSaleOrderDetail => soSaleOrderDetail.ShipCompleted.GetValueOrDefault(false));
                            // if all sale detail are completed, mark the master as completed
                            if (isCompleted)
                            {
                                saleOrderMaster.ShipCompleted = true;
                            }
                        }
                        db.SubmitChanges();
                        
                        #endregion
                    }
                    catch (SqlException ex)
                    {
                        if (ex.Errors.Count > 1)
                        {
                            if (ex.Number == ErrorCode.SQLDUPLICATE_KEYCODE)
                                throw new PCSDBException(ErrorCode.DUPLICATE_KEY, METHOD_NAME, ex);
                            throw new PCSDBException(ErrorCode.ERROR_DB, METHOD_NAME, ex);
                        }
                        throw new PCSDBException(ErrorCode.ERROR_DB, METHOD_NAME, ex);
                    }
                    catch (PCSBOException ex)
                    {
                        if (ex.mCode == ErrorCode.MESSAGE_MATERIALISSUE_INVALID_ISSUE_QTY)
                            throw new PCSDBException(ErrorCode.MESSAGE_NOT_ENOUGH_COMPONENT_TO_COMPLETE, METHOD_NAME, ex);
                        throw new PCSDBException(ErrorCode.ERROR_DB, METHOD_NAME, ex);
                    }
                }
                trans.Complete();
            }



            return intMasterID;
        }
	}
}
